package apiserver

import (
	"bytes"
	"io/ioutil"

	"sales-web/server/config"
	"sales-web/server/dal"
	"sales-web/server/handlers"
	"sales-web/server/pkg/logutil"

	"github.com/gin-contrib/pprof"
	"github.com/gin-gonic/gin"
	log "github.com/sirupsen/logrus"
)

const logPath = "logs/api-server.log"

var (
	// logFilePath use to define produce log path.
	logFilePath = logPath

	// hdl handler.
	hdl *handlers.Handler
)

func Run() error {
	// Init log.
	var logLevel = "info"
	cfg := config.GetGlobalCfg()
	if cfg.Debug {
		logLevel = "debug"
	}
	logutil.InitLog(logFilePath, logLevel)
	// Init mysql.
	db, err := dal.Open(cfg.MySQL)
	if err != nil {
		return err
	}

	var userCount int64
	db.Model(dal.User{}).Count(&userCount)
	if userCount == 0 {
		db.Create(&dal.User{
			Username: "admin",
			Nickname: "Admin",
			Password: "admin",
			Role:     "super_admin",
		})
	}

	// Init handler.
	hdl = handlers.New(
		handlers.WithDBC(db),
	)

	var r = &gin.Engine{}
	r = gin.Default()

	r.Use(gin.Recovery())
	r.Use(requestLogger())
	r.Use(logutil.Logger(log.StandardLogger()))

	if cfg.Debug {
		pprof.Register(r, "/debug/pprof/")
	}

	routeRegister(hdl, r)
	return r.Run(":" + cfg.ListenPort)
}

func requestLogger() gin.HandlerFunc {
	return func(c *gin.Context) {
		buf, _ := ioutil.ReadAll(c.Request.Body)
		rdr2 := ioutil.NopCloser(bytes.NewBuffer(buf)) // We have to create a new Buffer, because rdr1 will be read.
		if len(buf) > 0 {
			log.Infof("==== request body :%s ====", string(buf))
		}
		c.Request.Body = rdr2
		c.Next()
	}
}
